﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SolidWorks.Interop.swconst;
using SwParaPlatform2.logger;

namespace SwParaPlatform2.dlgFormula
{
    public interface IFileSelector
    {
        /// <summary>
        /// 显示文件选择对话框并返回选择的文件路径
        /// </summary>
        /// <returns>选中的文件路径，如果未选则返回null</returns>
        string SelectFile();
    }


    public partial class dlgFormulaMain : Form
    {
        public List<Dictionary<string, object>> lFormulaList;

        public Dictionary<string, string> dSelectedValue;
        public Dictionary<string, object> dSelectNestDict;
        public List<string> lPropList { get; private set; }
        public string sSelectProp;

        private readonly ISwParaInterface _commonInterface;
        private readonly IFileSelector fileSelector = new SolidWorksFileSelector();

        public Dictionary<string, Dictionary<string, object>> dDataGridView;

        public dlgFormulaMain(Dictionary<string, object> dNestDict, List<Dictionary<string, object>> FormulaList)
        {
            _commonInterface = new SwParaInterface();
            lPropList = new List<string>();
            lFormulaList = FormulaList;
            dDataGridView = new Dictionary<string, Dictionary<string, object>>();
            dSelectNestDict = dNestDict;
            InitializeComponent();
            Init();
            OnFormulaListChange2();
        }

        private void Init()
        {
            InitPropList();
            SetPropList();

            dataGridView1.SelectionChanged += DataGridView_SelectionChanged;

            dataGridView1.Columns["PropCol"].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
            dataGridView1.Columns["PropCol"].Width = 150; // 设置固定宽度
        }

        public void InitPropList()
        {
            string sElementType = (string)dSelectNestDict["TypeName"];
            if (Defines.MateList.Contains(sElementType))
            {
                AppendPropListValue("压缩");
                swMateType_e sMateType = (swMateType_e)dSelectNestDict["MateType"];
                if(sMateType == swMateType_e.swMateDISTANCE || sMateType == swMateType_e.swMateANGLE)
                {
                    AppendPropListValue("尺寸");
                }
            }
            else
            {
                if (Defines.DimList.Contains(sElementType))
                {
                    AppendPropListValue("尺寸");
                }
                if (Defines.CompressList.Contains(sElementType))
                {
                    AppendPropListValue("压缩");
                }
                if (Defines.ComponentList.Contains(sElementType))
                {
                    AppendPropListValue("压缩");
                    AppendPropListValue("替换");
                }
                if (Defines.EquationList.Contains(sElementType))
                {
                    AppendPropListValue("尺寸");
                    AppendPropListValue("压缩");
                }
                if (Defines.SpLineList.Contains(sElementType))
                {
                    AppendPropListValue("方程式曲线");
                }
            }
        }

        public void AppendPropListValue(string sValue)
        {
            if (!lPropList.Contains(sValue))
            {
                lPropList.Add(sValue);
            }
        }

        public void SetPropList()
        {
            PropList.Items.Clear();
            foreach (var item in lPropList)
            {
                PropList.Items.Add(item);
            }

            if(lPropList.Count() == 1)
            {
                SetComboBoxValue(lPropList[0]);
                PropList.Enabled = false;
            }
        }

        public Dictionary<string, object> GetFormulaDict(string sArgs, string sFullPath, string Type)
        {
            int subListLen = GetSubListLen(sArgs);
            if (Type == Defines.Type_Number 
                && double.TryParse(sArgs, out double sNum)
                && checkBox1.Checked)
            {
                sNum = sNum / 1000.0;
                sArgs = sNum.ToString();
            }
            var ArgDict = new Dictionary<string, object>{
                {"Type", Type},
                {"Value", sArgs},
                {"FullPath", sFullPath},
                {"SubListLen", subListLen},
                {"SubList", new List<Dictionary<string, object>>() },
            };
            return ArgDict;
        }

        public void AddFormula(string sArgs, string sFullPath, string Type)
        {
            Dictionary<string, object> AddArg = GetFormulaDict(sArgs, sFullPath, Type);

            lFormulaList.Add(AddArg);

            OnFormulaListChange2();
        }

        public void OnFormulaListChange()
        {
            string sFormula = _commonInterface.ExecArgsList(lFormulaList);
            //FormulaLabel.Text = sFormula;
        }

        public void OnFormulaListChange2()
        {
            FormulaLabel2.Text = "";
            foreach (var dFormula in lFormulaList)
            {
                string sFormula = "";
                string sType = (string)dFormula["Type"];
                string sValue = (string)dFormula["Value"];
                Color oColor = Color.Black;
                if (Defines.Type_List_Quot.Contains(sType))
                {
                    sFormula = $"'{sValue}'";
                }
                else
                {
                    sFormula = sValue;
                    if (sType == Defines.Type_IF)
                    {
                        oColor = Color.Red;
                    }
                    else if (sType == Defines.Type_Bool)
                    {
                        oColor = Color.Blue;
                    }
                }
                FormulaLabel2.SelectionStart = FormulaLabel2.TextLength; // 设置插入位置
                FormulaLabel2.SelectionLength = 0; // 确保没有选中文本
                FormulaLabel2.SelectionColor = oColor; // 设置文本颜色
                FormulaLabel2.AppendText(sFormula); // 插入文本
                                                    // 将光标移动到文本的最后
                FormulaLabel2.SelectionStart = FormulaLabel2.Text.Length;
                // 滚动到光标位置
                FormulaLabel2.ScrollToCaret();
            }
            FormulaLabel2.SelectionStart = FormulaLabel2.TextLength;
            FormulaLabel2.SelectionColor = FormulaLabel2.ForeColor;
            RefreshFreeInput();
        }

        public void RefreshFreeInput()
        {
            DropList.Items.Clear();
            if (lFormulaList.Count >= 2)
            {
                var lastElement = lFormulaList[lFormulaList.Count - 1];       // 倒数第一个元素
                var secondLastElement = lFormulaList[lFormulaList.Count - 2]; // 倒数第二个元素

                string lastElementValue = (string)lastElement["Value"];
                string secondLastElementType = (string)secondLastElement["Type"];

                if(lastElementValue == "=" && secondLastElementType == Defines.Type_Arg)
                {
                    string sArg = (string)secondLastElement["Value"];
                    var ArgData = dlgUIConfig.UIConfigModel.Instance.GetGridDataDict()[sArg];
                    string sInputType = (string)ArgData["输入类型"];
                    if(sInputType != "自由填写")
                    {
                        List<string> lData = (List<string>)ArgData["输入列表"];
                        DropList.Items.AddRange(lData.ToArray());
                        NumInput.Text = "";
                        DropList.Visible = true;
                        NumInput.Visible = false;
                        ShowToolTip(DropList, "选择参数值并插入到公式");
                    }
                    else
                    {
                        DropList.Text = string.Empty; // 清空选中的文本
                        DropList.Visible = false;
                        NumInput.Visible = true;
                    }
                }
                else
                {
                    DropList.Text = string.Empty; // 清空选中的文本
                    DropList.Visible = false;
                    NumInput.Visible = true;
                }
            }
            else
            {
                DropList.Text = string.Empty; // 清空选中的文本
                DropList.Visible = false;
                NumInput.Visible = true;
            }
        }

        private void ShowToolTip(Control control, string message)
        {
            ToolTip toolTip = new ToolTip();
            toolTip.IsBalloon = true;
            toolTip.Show(message, control, 0, -50, 1000); // 在控件上方显示，持续2秒
        }

        public void RefreshDataGrid()
        {
            try
            {
                if(dataGridView1.Rows.Count > 0)
                {
                    dataGridView1.Rows.Clear();
                }
                
                foreach (var kv in dDataGridView)
                {
                    var rowIndex = dataGridView1.Rows.Add();
                    var row = dataGridView1.Rows[rowIndex];

                    var sPropName = kv.Key;
                    var FormulaInfo = kv.Value;
                    string sFormula = (string)FormulaInfo["sFormula"];

                    row.Cells[PropCol.Index].Value = sPropName;
                    row.Cells[FormulaCol.Index].Value = sFormula;
                }
            }
            catch (Exception ex)
            {
                Logger.Instance.Log($"dataGridView1清理失败=========={this.GetHashCode()}");
                Logger.Instance.Log("Error clearing DataGridView: " + ex.Message);
            }
            
        }

        private void SetComboBoxValue(string value)
        {
            int index = PropList.Items.IndexOf(value);
            if (index >= 0)
            {
                PropList.SelectedIndex = index; // 设置选定值
                PropList_SelectedIndexChanged(PropList, EventArgs.Empty); // 手动触发事件
            }
        }

        private void AddFormula()
        {
            dDataGridView[sSelectProp] = new Dictionary<string, object>
            {
                {"sFormula", FormulaLabel2.Text},
                {"lFormulaList", lFormulaList},
            };
            RefreshDataGrid();
            lFormulaList = new List<Dictionary<string, object>>();
            FormulaLabel2.Text = "";
        }

        private void OnClickFinish()
        {
            SaveConfirmationDialog dialog = new SaveConfirmationDialog();

            // 保存操作
            void SaveOperation()
            {
                // 调用保存逻辑函数
                SaveFormula();
            }

            // 不保存操作
            void DiscardOperation()
            {
                // 调用放弃保存逻辑函数
                CloseWithoutSaving();
            }

            if(!string.IsNullOrEmpty(FormulaLabel2.Text))
            {
                // 显示弹窗，传入两个操作函数
                dialog.ShowDialog(SaveOperation, DiscardOperation);
            }
            else
            {
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void SaveFormula()
        {
            // 执行保存逻辑
            Logger.Instance.Log("执行保存操作");
            // 可以替换为实际保存函数，例如：
            // FormulaManager.SaveAll();
            AddFormula();
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void CloseWithoutSaving()
        {
            // 执行放弃保存逻辑
            Logger.Instance.Log("放弃保存，直接关闭");
            // 可以替换为实际关闭函数，例如：
            // FormulaManager.DiscardChanges();
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        public int GetSubListLen(string sArgs)
        {
            return 0;
        }

        public string GetArgType(string sArgs)
        {
            return "Arg";
        }


        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 检查是否选中了一行
            if (dataGridView1.SelectedRows.Count > 0)
            {
                // 获取选中行的第一个索引
                var selectedRow = dataGridView1.SelectedRows[0];

                // 获取PropCol列的值
                var key = selectedRow.Cells["PropCol"].Value as string;

                // 检查key是否不为空并存在于字典中
                if (!string.IsNullOrEmpty(key) && dDataGridView.ContainsKey(key))
                {
                    // 从字典中移除
                    dDataGridView.Remove(key);
                    RefreshDataGrid();
                }
                else
                {
                    MessageBox.Show("选中的Key不存在或未找到。");
                }
            }
            else
            {
                MessageBox.Show("请选中DataGridView中的一行。");
            }
        }

        private void PropList_SelectedIndexChanged(object sender, EventArgs e)
        {
            sSelectProp = PropList.SelectedItem.ToString();
            On_PropList_SelectedIndexChanged();
        }

        private void On_PropList_SelectedIndexChanged()
        {
            FileBtn.Visible = sSelectProp == "替换";
            btnY.Visible = sSelectProp == "方程式曲线";
            btnX1.Visible = sSelectProp == "方程式曲线";
            btnX2.Visible = sSelectProp == "方程式曲线";
            btnSplit.Visible = sSelectProp == "方程式曲线";
        }

        private void ArgsBtn_Click(object sender, EventArgs e)
        {
            using (dlgParaSelect oSelectParaView = new dlgParaSelect())
            {
                WindowAlignmentHelper.Align(this, oSelectParaView, WindowAlignmentHelper.Alignment.Center);
                if (oSelectParaView.ShowDialog() == DialogResult.OK)
                {
                    // 获取选中的项
                    string selectedValue = oSelectParaView.SelectedItem;

                    AddFormula(selectedValue, "", Defines.Type_Arg);

                    Logger.Instance.Log($"Select canshu {selectedValue}");
                }
            }
        }

        private void ElementBtn_Click(object sender, EventArgs e)
        {
            using(dlgElementSelect oSelectElementView = new dlgElementSelect())
            {
                if (oSelectElementView.ShowDialog() == DialogResult.OK)
                {
                    // 获取选中的项
                    dSelectedValue = oSelectElementView.dSelectedItem;
                    string sElementName = dSelectedValue["Element"];
                    string sElementNameFullPath = dSelectedValue["FullPath"];

                    AddFormula(sElementName, sElementNameFullPath, Defines.Type_Element);
                }
            }
        }

        private void NumBtn_Click(object sender, EventArgs e)
        {
            if (NumInput.Visible)
            {
                string sContent = NumInput.Text;
                if (double.TryParse(sContent, out double sNum))
                {
                    AddFormula(sContent, "", Defines.Type_Number);
                }
                else
                {
                    AddFormula(sContent, "", Defines.Type_String);
                }
                NumInput.Text = "";
            }
            else if (DropList.Visible)
            {
                string sSelect = DropList.Text;
                if (double.TryParse(sSelect, out double sNum))
                {
                    AddFormula(sSelect, "", Defines.Type_Number);
                }
                else
                {
                    AddFormula(sSelect, "", Defines.Type_String);
                }
                DropList.Items.Clear();
            }
            
        }

        private void TrueBtn_Click(object sender, EventArgs e)
        {
            AddFormula("true", "", Defines.Type_Bool);
        }

        private void FalseBtn_Click(object sender, EventArgs e)
        {
            AddFormula("false", "", Defines.Type_Bool);
        }

        private void IFBtn_Click(object sender, EventArgs e)
        {
            AddFormula("IF", "", Defines.Type_IF);
        }

        private void CutBtn_Click(object sender, EventArgs e)
        {
            AddFormula("|,|", "", Defines.Type_Split);
        }

        private void JiaBtn_Click(object sender, EventArgs e)
        {
            AddFormula("+", "", Defines.Type_Ope);
        }

        private void JianBtn_Click(object sender, EventArgs e)
        {
            AddFormula("-", "", Defines.Type_Ope);
        }

        private void ChengBtn_Click(object sender, EventArgs e)
        {
            AddFormula("*", "", Defines.Type_Ope);
        }

        private void ChuBtn_Click(object sender, EventArgs e)
        {
            AddFormula("÷", "", Defines.Type_Ope);
        }

        private void DengBtn_Click(object sender, EventArgs e)
        {
            AddFormula("=", "", Defines.Type_Ope);
        }

        private void LeftBtn_Click(object sender, EventArgs e)
        {
            AddFormula("(", "", Defines.Type_Ope);
        }

        private void RightBtn_Click(object sender, EventArgs e)
        {
            AddFormula(")", "", Defines.Type_Ope);
        }

        private void BackBtn_Click(object sender, EventArgs e)
        {
            lFormulaList.RemoveAt(lFormulaList.Count - 1);
            OnFormulaListChange2();
        }

        private void AddBtn_Click(object sender, EventArgs e)
        {
            AddFormula();
        }

        private void DataGridView_SelectionChanged(object sender, EventArgs e)
        {
            if (dataGridView1.Rows.Count > 0 && dataGridView1.SelectedRows.Count > 0)
            {
                var selectedRow = dataGridView1.SelectedRows[0];
                // 确保“参数”列存在
                if (dataGridView1.Columns["PropCol"] != null)
                {
                    // 获取名为“参数”的列的索引
                    int columnIndex = dataGridView1.Columns["PropCol"].Index;
                    // 获取选中行中“参数”列的值
                    var cellValue = selectedRow.Cells[columnIndex].Value;
                    if (cellValue != null) // 确保单元格中的值不是null
                    {
                        var parameterValue = cellValue.ToString();
                        lFormulaList = (List<Dictionary<string, object>>)dDataGridView[parameterValue]["lFormulaList"];
                        SetComboBoxValue(parameterValue);
                        OnFormulaListChange2();
                    }
                }
            }
            
        }

        private void OKBtn_Click(object sender, EventArgs e)
        {
            OnClickFinish();
        }

        private void OtherBtn_Click(object sender, EventArgs e)
        {
            using (dlgOtherOpe oOtherOpeView = new dlgOtherOpe())
            {
                WindowAlignmentHelper.Align(this, oOtherOpeView, WindowAlignmentHelper.Alignment.Center);
                if (oOtherOpeView.ShowDialog() == DialogResult.OK)
                {
                    // 获取选中的项
                    string sOpe = oOtherOpeView.sOpe;
                    AddFormula(sOpe, "", Defines.Type_Ope);
                }
            }
        }

        private void FileBtn_Click(object sender, EventArgs e)
        {
            string filePath = fileSelector.SelectFile();

            if (!string.IsNullOrEmpty(filePath))
            {
                Logger.Instance.Log($"已选择文件: {filePath}");
                AddFormula(filePath, "", Defines.Type_RepFilePath);
            }
        }

        private void btnY_Click(object sender, EventArgs e)
        {
            AddFormula("y", "", Defines.Type_SpLine);
        }

        private void btnX1_Click(object sender, EventArgs e)
        {
            AddFormula("x1", "", Defines.Type_SpLine);
        }

        private void btnX2_Click(object sender, EventArgs e)
        {
            AddFormula("x2", "", Defines.Type_SpLine);
        }

        private void btnSplit_Click(object sender, EventArgs e)
        {
            AddFormula(Defines.SpLine_Split, "", Defines.Type_Split);
        }

        private void ceil_up_btn_Click_1(object sender, EventArgs e)
        {
            AddFormula("Ceil", "", Defines.Type_Ope);
        }

        private void floor_down_btn_Click(object sender, EventArgs e)
        {
            AddFormula("Floor", "", Defines.Type_Ope);
        }

        private void AndBtn_Click(object sender, EventArgs e)
        {
            AddFormula("And", "", Defines.And_Split);
        }

        private void OrBtn_Click(object sender, EventArgs e)
        {
            AddFormula("or", "", Defines.Or_Split);
        }
    }

    public class SolidWorksFileSelector : IFileSelector
    {
        private string _lastSelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

        /// <summary>
        /// 显示文件选择器
        /// </summary>
        public string SelectFile()
        {
            using (var openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Title = "请选择SolidWorks文件";
                openFileDialog.Filter = "SolidWorks文件 (*.sldprt;*.sldasm)|*.sldprt;*.sldasm";
                openFileDialog.InitialDirectory = _lastSelectedPath;
                openFileDialog.RestoreDirectory = true;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    _lastSelectedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    return openFileDialog.FileName;
                }
            }

            return null;
        }
    }

    public class SaveConfirmationDialog
    {
        /// <summary>
        /// 显示未保存公式的提示对话框
        /// </summary>
        /// <param name="onSave">点击“保存”时执行的回调</param>
        /// <param name="onDiscard">点击“不保存”时执行的回调</param>
        public void ShowDialog(Action onSave, Action onDiscard)
        {
            DialogResult result = MessageBox.Show(
                "当前存在未保存的公式，是否保存并关闭界面？",
                "未保存公式",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Warning,
                MessageBoxDefaultButton.Button1);

            if (result == DialogResult.Yes)
            {
                // 点击“保存”按钮时执行回调函数
                onSave?.Invoke();
            }
            else if (result == DialogResult.No)
            {
                // 点击“不保存”按钮时执行回调函数
                onDiscard?.Invoke();
            }
        }
    }
}
